package cn.jtool.dig.server.comm.tunnel.protocol;

import cn.jtool.dig.common.model.*;
import cn.jtool.dig.common.netty.CtxUtils;
import cn.jtool.dig.common.netty.ProtocolProcess;
import cn.jtool.dig.common.netty.SNGenerator;
import cn.jtool.dig.common.netty.SessionManager;
import cn.jtool.dig.server.comm.tunnel.TunnelAttrKey;
import cn.jtool.dig.server.dao.entity.License;
import cn.jtool.dig.server.service.LicenseService;
import cn.jtool.knife.core.result.ResultEntity;
import io.netty.channel.ChannelHandlerContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Component
public class P_15_Auth implements ProtocolProcess {

    @Resource
    private LicenseService licenseService;

    @Override
    public int protocolId() {
        return Commands.AUTH.getCode();
    }

    @Override
    public Packet process(ChannelHandlerContext ctx, Packet packet) {
        PacketHeader header = packet.getHeader();
        PacketBody body = packet.getBody();
        int secretKeyLength = body.readByte();
        String secretKey = body.readGbkString(secretKeyLength);
        ResultEntity<License> authResult = this.licenseService.auth(CtxUtils.getIp(ctx), secretKey);

        PacketHeader outHeader = PacketHeader.builder()
                .command(Commands.COMMON_RESPONSE.getCode()).channelId(header.getChannelId()).digId(0x00).sn(SNGenerator.gen()).build();
        PacketBody outBody = new PacketBody();
        outBody.writeByte(Commands.AUTH.getCode());
        outBody.writeWord(header.getSn());
        outBody.writeByte(authResult.getCode() == 0 ? 0 : 1);

        Packet outPacket = Packet.builder().header(outHeader).body(outBody).build();
        ctx.writeAndFlush(outPacket);

        if(authResult.getCode() == 0){
            CtxUtils.setAttribute(ctx, TunnelAttrKey.LICENSE, authResult.getData());
            CtxUtils.setAttribute(ctx, TunnelAttrKey.SESSION_ID, (long)authResult.getData().getId());
            SessionManager.addSession(
                    Session.builder()
                            .id(authResult.getData().getId())
                            .licenseId(authResult.getData().getId())
                            .sessionType(Session.SessionType.TUNNEL)
                            .channelHandlerContext(ctx)
                            .receiveBytes(new AtomicLong(0))
                            .sendBytes(new AtomicLong(0))
                            .heartbeatTime(System.currentTimeMillis())
                            .createTime(new Date())
                            .updateTime(new Date())
                            .build()
            );
        }else{
            ctx.channel().close();
        }
        return null;
    }
}
